package com.sixdog.regulate.adapter;

import com.sixdog.regulate.bean.Action;
import com.sixdog.regulate.bean.InvokeBean;
import com.sixdog.regulate.cmdService.HttpUtils;
import com.sixdog.regulate.service.*;
import com.sixdog.regulate.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

@Component
public class ActionAdapter {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private GestureService gestureService;
    @Autowired
    private ApkService apkService;
    @Autowired
    private KeycodeService keycodeService;
    @Autowired
    private ThreadService threadService;
    //执行动作对象（这个方法需在 动作设置的执行时间 之前执行，空出来的时间用来初始化，确保时间精准）
    public boolean executeAction(Action action) {

        //将所有可能被调用的接口对象放入数组
        ArrayList<Object> services = new ArrayList<>();
        services.add(deviceService);
        services.add(activityService);
        services.add(gestureService);
        services.add(apkService);
        services.add(keycodeService);
        services.add(threadService);
        //这个数组用来存放所有即将要执行的invokeBeans对象（即 接下来筛选出的内容 组成的对象）
        ArrayList<InvokeBean> invokeBeans = new ArrayList<>();
        //遍历动作对象指定的所有方法名，遍历接口对象的数组，对方法进行匹配。
        for (String funName:action.getFunctionNames()){
            for (Object obj:services){
                Arrays.asList(obj.getClass().getMethods()).forEach(method -> {
                            if (method.getName().equals(funName)){
                                //匹配到的方法对象，及其所需要的参数，封装成invokeBean对象。然后把invokeBean添加进数组invokeBeans
                                invokeBeans.add(new InvokeBean(method,obj,action.getArgsMap().get(funName)));
                            }
                        }
                );
            }
        }

        Date date = action.getDate();
        String dateServerName = action.getDateServerName();
        if (dateServerName!=null && !dateServerName.isEmpty()){
            HttpUtils.correctTimeWithServer(date,dateServerName);
        }



        //设置睡眠，矫正时间，精确到毫秒
        TimeUtils.sleepCorrectTiming(date,action.getAdvanceMillisecond());
        //到时间后执行所有的invokeBean.

        invokeBeans.forEach(invokeBean -> {
            invokeBean.exec();
        });

        return true;
    }

}
